package com.china.produce.scanner;

import com.china.produce.annotation.RequiresRoles;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * 获取方法上带有自定义注解
 *
 * @ClassName
 * @Author niujie
 * @Version
 * @Description
 * @CreateTime 2024/8/10
 */
@Component
public class MethodWithAnnotationScanner implements ApplicationContextAware {

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

        HashMap<Method, List<String>> methodWithAnnotationList = new HashMap<>();

        String[] beanNames = applicationContext.getBeanNamesForType(Object.class);

        //MethodIntrospector 可以被看作是一个用于深入检查（introspect）类的方法的工具类。它可能提供了多种方法来查询、筛选或操作类的方法。
        //selectMethods 方法则可能是这个类中的一个方法，用于根据特定的条件或标准来选择或过滤出类中的一组方法
        for (String beanName : beanNames) {
            Object bean = applicationContext.getBean(beanName);
            Map<Method, RequiresRoles> methodObjectMap = MethodIntrospector.selectMethods(bean.getClass(), new MethodIntrospector.MetadataLookup<RequiresRoles>() {
                @Override
                public RequiresRoles inspect(Method method) {

                    return AnnotatedElementUtils.findMergedAnnotation(method, RequiresRoles.class);
                }
            });

            for (Map.Entry<Method, RequiresRoles> entry : methodObjectMap.entrySet()) {

                Method key = entry.getKey();

                String[] values = entry.getValue().value();

                for (String value : values) {

                    methodWithAnnotationList.computeIfAbsent(key, item -> new ArrayList<String>()).add(value);
                }
            }
        }
    }
}
